/*
 * Copyright 2002-2021 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.transaction.annotation;

import org.springframework.core.annotation.AliasFor;
import org.springframework.transaction.TransactionDefinition;

import java.lang.annotation.*;

/**
 * Describes a transaction attribute on an individual method or on a class.
 *
 * <p>When this annotation is declared at the class level, it applies as a default
 * to all methods of the declaring class and its subclasses. Note that it does not
 * apply to ancestor classes up the class hierarchy; inherited methods need to be
 * locally redeclared in order to participate in a subclass-level annotation. For
 * details on method visibility constraints, consult the
 * <a href="https://docs.spring.io/spring-framework/docs/current/reference/html/data-access.html#transaction">Transaction Management</a>
 * section of the reference manual.
 *
 * <p>This annotation type is generally directly comparable to Spring's
 * {@link org.springframework.transaction.interceptor.RuleBasedTransactionAttribute}
 * class, and in fact {@link AnnotationTransactionAttributeSource} will directly
 * convert the data to the latter class, so that Spring's transaction support code
 * does not have to know about annotations. If no custom rollback rules apply,
 * the transaction will roll back on {@link RuntimeException} and {@link Error}
 * but not on checked exceptions.
 *
 * <p>For specific information about the semantics of this annotation's attributes,
 * consult the {@link org.springframework.transaction.TransactionDefinition} and
 * {@link org.springframework.transaction.interceptor.TransactionAttribute} javadocs.
 *
 * <p>This annotation commonly works with thread-bound transactions managed by a
 * {@link org.springframework.transaction.PlatformTransactionManager}, exposing a
 * transaction to all data access operations within the current execution thread.
 * <b>Note: This does NOT propagate to newly started threads within the method.</b>
 *
 * <p>Alternatively, this annotation may demarcate a reactive transaction managed
 * by a {@link org.springframework.transaction.ReactiveTransactionManager} which
 * uses the Reactor context instead of thread-local variables. As a consequence,
 * all participating data access operations need to execute within the same
 * Reactor context in the same reactive pipeline.
 *
 * @author Colin Sampaleanu
 * @author Juergen Hoeller
 * @author Sam Brannen
 * @since 1.2
 * @see org.springframework.transaction.interceptor.TransactionAttribute
 * @see org.springframework.transaction.interceptor.DefaultTransactionAttribute
 * @see org.springframework.transaction.interceptor.RuleBasedTransactionAttribute
 */
// 描述单个方法或类的事务属性。
// 在类级别声明此注解时，它默认应用于声明类及其子类的所有方法。 请注意，它不适用于类层次结构中的祖先类；
// 继承的方法需要在本地重新声明才能参与子类级别的注释。 有关方法可见性约束的详细信息，请参阅参考手册的事务管理 部分。
// 这种注解类型一般可以直接媲美Spring的org.springframework.transaction.interceptor.RuleBasedTransactionAttribute类，
// 实际上AnnotationTransactionAttributeSource会直接将数据转换为后一个类，这样Spring的事务支持代码就不用知道注解了。
// 如果没有应用自定义回滚规则，事务将在RuntimeException和Error上回滚，但不会在检查的异常上回滚。
// 有关此注解属性语义的具体信息，
// 请参阅TransactionDefinition和org.springframework.transaction.interceptor.TransactionAttribute javadocs。
// 此注解通常与由org.springframework.transaction.PlatformTransactionManager管理的线程绑定事务一起使用，将事务公开给当前执行线程中的所有数据访问操作。
// 注意：这不会传播到方法中新启动的线程。
// 或者，此注解可以划分由org.springframework.transaction.ReactiveTransactionManager管理的反应式事务，该事务使用 Reactor 上下文而不是线程局部变量。
// 因此，所有参与的数据访问操作都需要在同一个反应式管道中的同一个 Reactor 上下文中执行。
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {

	/**
	 * Alias for {@link #transactionManager}.
	 * @see #transactionManager
	 */
	@AliasFor("transactionManager")
	String value() default "";

	/**
	 * A <em>qualifier</em> value for the specified transaction.
	 * <p>May be used to determine the target transaction manager, matching the
	 * qualifier value (or the bean name) of a specific
	 * {@link org.springframework.transaction.TransactionManager TransactionManager}
	 * bean definition.
	 * @since 4.2
	 * @see #value
	 * @see org.springframework.transaction.PlatformTransactionManager
	 * @see org.springframework.transaction.ReactiveTransactionManager
	 */
	// 指定事务的限定符值。
	// 可用于确定目标事务管理器，匹配特定TransactionManager bean 定义的限定符值（或 bean 名称）。
	@AliasFor("value")
	String transactionManager() default "";

	/**
	 * The transaction propagation type.
	 * <p>Defaults to {@link Propagation#REQUIRED}.
	 * @see org.springframework.transaction.interceptor.TransactionAttribute#getPropagationBehavior()
	 */
	// 事务传播类型。
	// 默认为Propagation.REQUIRED 。
	Propagation propagation() default Propagation.REQUIRED;

	/**
	 * The transaction isolation level.
	 * <p>Defaults to {@link Isolation#DEFAULT}.
	 * <p>Exclusively designed for use with {@link Propagation#REQUIRED} or
	 * {@link Propagation#REQUIRES_NEW} since it only applies to newly started
	 * transactions. Consider switching the "validateExistingTransactions" flag to
	 * "true" on your transaction manager if you'd like isolation level declarations
	 * to get rejected when participating in an existing transaction with a different
	 * isolation level.
	 * @see org.springframework.transaction.interceptor.TransactionAttribute#getIsolationLevel()
	 * @see org.springframework.transaction.support.AbstractPlatformTransactionManager#setValidateExistingTransaction
	 */
	// 事务隔离级别。
	// 默认为Isolation.DEFAULT 。
	// 专为与Propagation.REQUIRED或Propagation.REQUIRES_NEW一起使用而设计，因为它仅适用于新启动的事务。
	// 如果您希望在参与具有不同隔离级别的现有事务时拒绝隔离级别声明，请考虑将事务管理器上的“validateExistingTransactions”标志切换为“true”。
	Isolation isolation() default Isolation.DEFAULT;

	/**
	 * The timeout for this transaction (in seconds).
	 * <p>Defaults to the default timeout of the underlying transaction system.
	 * <p>Exclusively designed for use with {@link Propagation#REQUIRED} or
	 * {@link Propagation#REQUIRES_NEW} since it only applies to newly started
	 * transactions.
	 * @see org.springframework.transaction.interceptor.TransactionAttribute#getTimeout()
	 */
	// 此事务的超时时间（以秒为单位）。
	// 默认为底层事务系统的默认超时。
	// 专为与Propagation.REQUIRED或Propagation.REQUIRES_NEW一起使用而设计，因为它仅适用于新启动的事务
	int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;

	/**
	 * A boolean flag that can be set to {@code true} if the transaction is
	 * effectively read-only, allowing for corresponding optimizations at runtime.
	 * <p>Defaults to {@code false}.
	 * <p>This just serves as a hint for the actual transaction subsystem;
	 * it will <i>not necessarily</i> cause failure of write access attempts.
	 * A transaction manager which cannot interpret the read-only hint will
	 * <i>not</i> throw an exception when asked for a read-only transaction
	 * but rather silently ignore the hint.
	 * @see org.springframework.transaction.interceptor.TransactionAttribute#isReadOnly()
	 * @see org.springframework.transaction.support.TransactionSynchronizationManager#isCurrentTransactionReadOnly()
	 */
	// 如果事务实际上是只读的，则可以设置为true的布尔标志，允许在运行时进行相应的优化。
	// 默认为false 。
	// 这只是作为实际事务子系统的提示； 它不一定会导致写访问尝试失败。
	// 无法解释只读提示的事务管理器在请求只读事务时不会抛出异常，而是默默地忽略提示。
	boolean readOnly() default false;

	/**
	 * Defines zero (0) or more exception {@link Class classes}, which must be
	 * subclasses of {@link Throwable}, indicating which exception types must cause
	 * a transaction rollback.
	 * <p>By default, a transaction will be rolling back on {@link RuntimeException}
	 * and {@link Error} but not on checked exceptions (business exceptions). See
	 * {@link org.springframework.transaction.interceptor.DefaultTransactionAttribute#rollbackOn(Throwable)}
	 * for a detailed explanation.
	 * <p>This is the preferred way to construct a rollback rule (in contrast to
	 * {@link #rollbackForClassName}), matching the exception class and its subclasses.
	 * <p>Similar to {@link org.springframework.transaction.interceptor.RollbackRuleAttribute#RollbackRuleAttribute(Class clazz)}.
	 * @see #rollbackForClassName
	 * @see org.springframework.transaction.interceptor.DefaultTransactionAttribute#rollbackOn(Throwable)
	 */
	// 定义零 (0) 个或多个异常classes ，它们必须是Throwable的子类，指示哪些异常类型必须导致事务回滚。
	// 默认情况下，事务将在RuntimeException和Error上回滚，但不会在已检查异常（业务异常）上回滚。
	// 有关详细说明，请参见org.springframework.transaction.interceptor.DefaultTransactionAttribute.rollbackOn(Throwable) 。
	// 这是构造回滚规则的首选方式（与rollbackForClassName相比），匹配异常类及其子类。
	// 类似于org.springframework.transaction.interceptor.RollbackRuleAttribute.RollbackRuleAttribute(Class clazz) 。
	Class<? extends Throwable>[] rollbackFor() default {};

	/**
	 * Defines zero (0) or more exception names (for exceptions which must be a
	 * subclass of {@link Throwable}), indicating which exception types must cause
	 * a transaction rollback.
	 * <p>This can be a substring of a fully qualified class name, with no wildcard
	 * support at present. For example, a value of {@code "ServletException"} would
	 * match {@code javax.servlet.ServletException} and its subclasses.
	 * <p><b>NB:</b> Consider carefully how specific the pattern is and whether
	 * to include package information (which isn't mandatory). For example,
	 * {@code "Exception"} will match nearly anything and will probably hide other
	 * rules. {@code "java.lang.Exception"} would be correct if {@code "Exception"}
	 * were meant to define a rule for all checked exceptions. With more unusual
	 * {@link Exception} names such as {@code "BaseBusinessException"} there is no
	 * need to use a FQN.
	 * <p>Similar to {@link org.springframework.transaction.interceptor.RollbackRuleAttribute#RollbackRuleAttribute(String exceptionName)}.
	 * @see #rollbackFor
	 * @see org.springframework.transaction.interceptor.DefaultTransactionAttribute#rollbackOn(Throwable)
	 */
	// 定义零 (0) 个或多个异常名称（对于必须是Throwable子类的异常），指示哪些异常类型必须导致事务回滚。
	// 这可以是完全限定类名的子字符串，目前不支持通配符。 例如， "ServletException"的值将匹配javax.servlet.ServletException及其子类。
	// 注意：仔细考虑模式的具体程度以及是否包含包信息（这不是强制性的）。
	// 例如， "Exception"将匹配几乎所有内容，并且可能会隐藏其他规则。
	// 如果"Exception"旨在为所有检查的异常定义规则，则"java.lang.Exception"将是正确的。
	// 对于更不寻常的Exception名称，例如"BaseBusinessException" ，无需使用 FQN。
	// 类似于org.springframework.transaction.interceptor.RollbackRuleAttribute.RollbackRuleAttribute(String exceptionName) 。
	String[] rollbackForClassName() default {};

	/**
	 * Defines zero (0) or more exception {@link Class Classes}, which must be
	 * subclasses of {@link Throwable}, indicating which exception types must
	 * <b>not</b> cause a transaction rollback.
	 * <p>This is the preferred way to construct a rollback rule (in contrast
	 * to {@link #noRollbackForClassName}), matching the exception class and
	 * its subclasses.
	 * <p>Similar to {@link org.springframework.transaction.interceptor.NoRollbackRuleAttribute#NoRollbackRuleAttribute(Class clazz)}.
	 * @see #noRollbackForClassName
	 * @see org.springframework.transaction.interceptor.DefaultTransactionAttribute#rollbackOn(Throwable)
	 */
	// 定义零 (0) 个或多个异常Classes ，它们必须是Throwable的子类，指示哪些异常类型不得导致事务回滚。
	// 这是构造回滚规则的首选方式（与noRollbackForClassName ），匹配异常类及其子类。
	// 类似于org.springframework.transaction.interceptor.NoRollbackRuleAttribute.NoRollbackRuleAttribute(Class clazz) 。
	Class<? extends Throwable>[] noRollbackFor() default {};

	/**
	 * Defines zero (0) or more exception names (for exceptions which must be a
	 * subclass of {@link Throwable}) indicating which exception types must <b>not</b>
	 * cause a transaction rollback.
	 * <p>See the description of {@link #rollbackForClassName} for further
	 * information on how the specified names are treated.
	 * <p>Similar to {@link org.springframework.transaction.interceptor.NoRollbackRuleAttribute#NoRollbackRuleAttribute(String exceptionName)}.
	 * @see #noRollbackFor
	 * @see org.springframework.transaction.interceptor.DefaultTransactionAttribute#rollbackOn(Throwable)
	 */
	// 定义零 (0) 个或多个异常名称（对于必须是Throwable子类的异常），指示哪些异常类型不得导致事务回滚。
	// 有关如何处理指定名称的详细信息，请参阅rollbackForClassName的描述。
	// 类似于org.springframework.transaction.interceptor.NoRollbackRuleAttribute.NoRollbackRuleAttribute(String exceptionName) 。
	String[] noRollbackForClassName() default {};

}
